home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
001-100
/
001-025
/
023
/
ver30
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-17
|
6KB
|
290 lines
/*
* Name: MicroEMACS
* Mainline, macro commands.
* Version: 29
* Last edit: 05-Feb-86
* By: rex::conroy
* decvax!decwrl!dec-rhea!dec-rex!conroy
*/
#include "def.h"
int thisflag; /* Flags, this command */
int lastflag; /* Flags, last command */
int curgoal; /* Goal column */
BUFFER *curbp; /* Current buffer */
WINDOW *curwp; /* Current window */
BUFFER *bheadp; /* BUFFER listhead */
WINDOW *wheadp; /* WINDOW listhead */
BUFFER *blistp; /* Buffer list BUFFER */
short kbdm[NKBDM] = {(KCTLX|')')}; /* Macro */
short *kbdmip; /* Input for above */
short *kbdmop; /* Output for above */
char pat[NPAT]; /* Pattern */
SYMBOL *symbol[NSHASH]; /* Symbol table listhead. */
SYMBOL *binding[NKEYS]; /* Key bindings. */
main(argc, argv)
char *argv[];
{
register int c;
register int f;
register int n;
register int mflag;
char bname[NBUFN];
strcpy(bname, "main"); /* Get buffer name. */
if (argc > 1)
makename(bname, argv[1]);
vtinit(); /* Virtual terminal. */
edinit(bname); /* Buffers, windows. */
keymapinit(); /* Symbols, bindings. */
if (argc > 1) {
update();
readin(argv[1]);
}
lastflag = 0; /* Fake last flags. */
loop:
update(); /* Fix up the screen. */
c = getkey();
if (epresf != FALSE) {
eerase();
update();
}
f = FALSE;
n = 1;
if (c == (KCTRL|'U')) { /* ^U, start argument. */
f = TRUE;
n = 4;
while ((c=getkey()) == (KCTRL|'U'))
n *= 4;
if ((c>='0' && c<='9') || c=='-') {
if (c == '-') {
n = 0;
mflag = TRUE;
} else {
n = c - '0';
mflag = FALSE;
}
while ((c=getkey())>='0' && c<='9')
n = 10*n + c - '0';
if (mflag != FALSE)
n = -n;
}
}
if (kbdmip != NULL) { /* Save macro strokes. */
if (c!=(KCTLX|')') && kbdmip>&kbdm[NKBDM-6]) {
ctrlg(FALSE, 0, KRANDOM);
goto loop;
}
if (f != FALSE) {
*kbdmip++ = (KCTRL|'U');
*kbdmip++ = n;
}
*kbdmip++ = c;
}
execute(c, f, n); /* Do it. */
goto loop;
}
/*
* Command execution. Look up the binding in the the
* binding array, and do what it says. Return a very bad status
* if there is no binding, or if the symbol has a type that
* is not usable (there is no way to get this into a symbol table
* entry now). Also fiddle with the flags.
*/
execute(c, f, n)
{
register SYMBOL *sp;
register int status;
if ((sp=binding[c]) != NULL) {
thisflag = 0;
status = (*sp->s_funcp)(f, n, c);
lastflag = thisflag;
return (status);
}
lastflag = 0;
return (ABORT);
}
/*
* Initialize all of the buffers
* and windows. The buffer name is passed down as
* an argument, because the main routine may have been
* told to read in a file by default, and we want the
* buffer name to be right.
*/
edinit(bname)
char bname[];
{
register BUFFER *bp;
register WINDOW *wp;
bp = bfind(bname, TRUE); /* Text buffer. */
blistp = bcreate(""); /* Special list buffer. */
wp = (WINDOW *) malloc(sizeof(WINDOW)); /* Initial window. */
if (bp==NULL || wp==NULL || blistp==NULL)
abort();
curbp = bp; /* Current ones. */
wheadp = wp;
curwp = wp;
wp->w_wndp = NULL; /* Initialize window. */
wp->w_bufp = bp;
bp->b_nwnd = 1; /* Displayed. */
wp->w_linep = bp->b_linep;
wp->w_dotp = bp->b_linep;
wp->w_doto = 0;
wp->w_markp = NULL;
wp->w_marko = 0;
wp->w_toprow = 0;
wp->w_ntrows = nrow-2; /* 2 = mode, echo. */
wp->w_force = 0;
wp->w_flag = WFMODE|WFHARD; /* Full. */
}
/*
* Fancy quit command, as implemented
* by Jeff. If the current buffer has changed
* do a write current buffer. Otherwise run a command
* interpreter in a subjob. Two of these will get you
* out. Bound to "C-Z".
*/
jeffexit(f, n, k)
{
if ((curbp->b_flag&BFCHG) != 0) /* Changed. */
return (filesave(f, n, KRANDOM));
return (spawncli(f, n, KRANDOM)); /* Suspend. */
}
/*
* Quit command. If an argument, always
* quit. Otherwise confirm if a buffer has been
* changed and not written out. Normally bound
* to "C-X C-C".
*/
quit(f, n, k)
{
register int s;
if (f != FALSE /* Argument forces it. */
|| anycb() == FALSE /* All buffers clean. */
|| (s=eyesno("Quit")) == TRUE) { /* User says it's OK. */
vttidy();
exit(GOOD);
}
return (s);
}
/*
* Begin a keyboard macro.
* Error if not at the top level
* in keyboard processing. Set up
* variables and return.
*/
ctlxlp(f, n, k)
{
if (kbdmip!=NULL || kbdmop!=NULL) {
eprintf("Not now");
return (FALSE);
}
eprintf("[Start macro]");
kbdmip = &kbdm[0];
return (TRUE);
}
/*
* End keyboard macro. Check for
* the same limit conditions as the
* above routine. Set up the variables
* and return to the caller.
*/
ctlxrp(f, n, k)
{
if (kbdmip == NULL) {
eprintf("Not now");
return (FALSE);
}
eprintf("[End macro]");
kbdmip = NULL;
return (TRUE);
}
/*
* Execute a macro.
* The command argument is the
* number of times to loop. Quit as
* soon as a command gets an error.
* Return TRUE if all ok, else
* FALSE.
*/
ctlxe(f, n, k)
{
register int c;
register int af;
register int an;
register int s;
if (kbdmip!=NULL || kbdmop!=NULL) {
eprintf("Not now");
return (FALSE);
}
if (n <= 0)
return (TRUE);
do {
kbdmop = &kbdm[0];
do {
af = FALSE;
an = 1;
if ((c = *kbdmop++) == (KCTRL|'U')) {
af = TRUE;
an = *kbdmop++;
c = *kbdmop++;
}
s = TRUE;
} while (c!=(KCTLX|')') && (s=execute(c, af, an))==TRUE);
kbdmop = NULL;
} while (s==TRUE && --n);
return (s);
}
/*
* Abort.
* Beep the beeper.
* Kill off any keyboard macro,
* etc., that is in progress.
* Sometimes called as a routine,
* to do general aborting of
* stuff.
*/
ctrlg(f, n, k)
{
ttbeep();
if (kbdmip != NULL) {
kbdm[0] = (KCTLX|')');
kbdmip = NULL;
}
return (ABORT);
}
/*
* Display the version. All this does
* is copy the text in the external "version" array into
* the message system, and call the message reading code.
* Don't call display if there is an argument.
*/
showversion(f, n, k)
{
register char **cpp;
register char *cp;
cpp = &version[0];
while ((cp = *cpp++) != NULL) {
if (writemsg(cp) == FALSE)
return (FALSE);
}
if (f != FALSE) /* No display if arg. */
return (TRUE);
return (readmsg());
}